#include "stm32f4xx.h"
#include "voice_module.h"
#include <stddef.h>
#include "board.h"
#include "debug.h"

#define     USART_NUM_TX            GPIO_Pin_10
#define     USART_NUM_RX            GPIO_Pin_11
#define     USART_PORT              GPIOC
#define     USART_PINSOURCE_TX      GPIO_PinSource10
#define     USART_PINSOURCE_RX      GPIO_PinSource11
#define     USART_BOADRATE          9600    // 适配蓝牙透传串口波特率

voice_module_t  receive_extern_rx_func = NULL;   
extern QueueHandle_t voice_ctr_rx_binary;

void voice_module_init(void)
{   
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
 

    GPIO_PinAFConfig(USART_PORT, USART_PINSOURCE_TX, GPIO_AF_USART3); 
    GPIO_PinAFConfig(USART_PORT, USART_PINSOURCE_RX, GPIO_AF_USART3);
    
    GPIO_InitStructure.GPIO_Pin    = USART_NUM_TX | USART_NUM_RX;
    GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;             
    GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;        
    GPIO_InitStructure.GPIO_OType  = GPIO_OType_PP;            
    GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_UP;            
    GPIO_Init(USART_PORT, &GPIO_InitStructure);                    

    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
    USART_WakeUpConfig(USART3, USART_WakeUp_IdleLine); // 设置IDLE线唤醒

    USART_InitStructure.USART_BaudRate              = USART_BOADRATE;
    USART_InitStructure.USART_WordLength            = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits              = USART_StopBits_1;
    USART_InitStructure.USART_Parity                = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl   = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                  = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART3, &USART_InitStructure);
    USART_Cmd(USART3, ENABLE);
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
}

void voice_rx_func_register(voice_module_t callback)
{
    receive_extern_rx_func = callback;
}

void voice_module_send_command(uint8_t command)
{
    while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
    USART_SendData(USART3, command);
}

void USART3_IRQHandler(void)
{
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
        BaseType_t pxHigherPriorityTaskWoken;
        uint8_t data = USART_ReceiveData(USART3);
        // if(receive_extern_rx_func != NULL)
        // {
        //     receive_extern_rx_func(data);
        // }
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);
        // 发送任务通知
        xTaskNotifyFromISR(voice_task_handle, (uint32_t)data, eSetValueWithOverwrite, &pxHigherPriorityTaskWoken);
        // 判断是否需要执行任务切换
        if(pxHigherPriorityTaskWoken == pdTRUE)
        {
            portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
        }
    }
}

